#include "HerzeleidPrecompiled.hxx"
#include "HerzeleidCoreRenderer3.hxx"
using namespace HerzeleidRendererCoreNamespaceImpl;

CoreRenderer3::CoreRenderer3() : 
	IRenderer()
{
}

Void CoreRenderer3::Create(
	_In_opt_ D3D_FEATURE_LEVEL *pFeatureLevel /*= null */, 
	_In_opt_ D3D_DRIVER_TYPE eDriverType /*= D3D_DRIVER_TYPE_HARDWARE */
	)
{
	// This flag adds support for surfaces with a different color channel 
	// ordering than the Api default. It is required for compatibility with 
	// Direct2D. 
	UInt32 CreationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
#ifdef HERZELEID_DEBUG
	// If the project is in a debug build, enable debugging via the Sdk Layers 
	// with this flag. 
	CreationFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif

	// This array defines the set of DirectX hardware feature levels this 
	// app will support (the ordering should be preserved). 
	// This library is assumed to support 9.1.

	// Dx hardware feature level array.
	D3D_FEATURE_LEVEL FeatureLevels[] =
	{
		D3D_FEATURE_LEVEL_11_1,
		D3D_FEATURE_LEVEL_11_0,
		D3D_FEATURE_LEVEL_10_1,
		D3D_FEATURE_LEVEL_10_0,
		D3D_FEATURE_LEVEL_9_3,
		D3D_FEATURE_LEVEL_9_2,
		D3D_FEATURE_LEVEL_9_1
	};

	LockGuard Guard(m_Mtx); // Unlocks mutex when the function returns 
	WRL::ComPtr<ID3D11Device> lDevice3; // Direct3D Api Device object.
	WRL::ComPtr<ID3D11DeviceContext> lContext3; // Corresponding Direct3D 11 Api Device Context object. 

	DirectX::ThrowIfFailed( D3D11CreateDevice(
		_In_ nullptr,									// Specify nullptr to use the default adapter.
		_In_ eDriverType,								//_In_ D3D_DRIVER_TYPE::D3D_DRIVER_TYPE_HARDWARE, 
		_In_ nullptr,									// Specified if SOFTWARE device is desired. 
		_In_ CreationFlags, 							// Set debug and Direct2D compatibility flags.
		_In_ FeatureLevels,								// List of feature levels this app can support.
		_In_ ARRAYSIZE(FeatureLevels), 
		_In_ D3D11_SDK_VERSION, 
		// Create the DirectX Core Objects
		_Outptr_result_nullonfailure_ (&lDevice3),		// Returns the created d3d device
		_Outptr_result_nullonfailure_ (pFeatureLevel),	// Returns the device feature level
		_Outptr_result_nullonfailure_ (&lContext3)		// Returns the device immediate context
		) );

	// Get the Direct3D 11.1 API device and context interfaces.

	DirectX::ThrowIfFailed( 
		lDevice3.As(&m_Device3) 
		);
	DirectX::ThrowIfFailed(  
		lContext3.As(&m_ImmediateContext3) 
		);

	m_Device = m_Device3.Get();
	m_ImmediateContext = m_ImmediateContext3.Get();
}

DeferredContext3Ptr CoreRenderer3::CreateDeferredContext( _Inout_ WRL::ComPtr<DeferredContext3> &pDeferredContext )
{
	return DirectX::DemandCreate(pDeferredContext, m_Mtx, [this]( ID3D11DeviceContext1 **ppDeferredContext )
	{
		return m_Device3->CreateDeferredContext1( NoFlags, ppDeferredContext );
	});
}











